use crate::src::src::bloom_filter::{
    bloom_filter_free, bloom_filter_insert, bloom_filter_intersection, bloom_filter_load,
    bloom_filter_new, bloom_filter_query, bloom_filter_read, bloom_filter_union,
};
use crate::src::src::hash_string::{string_hash, string_nocase_hash};
use crate::src::struct_and_type::{BloomFilter, BloomFilterValue, UnitTestFunction};
use crate::src::test::alloc_testing::alloc_test_set_limit;
use crate::src::test::framework::run_tests;

#[no_mangle]
pub extern "C" fn test_bloom_filter_new_free() {
    let mut filter: *mut BloomFilter = 0 as *mut BloomFilter;
    filter = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 1 as u32,
    );
    assert!(!filter.is_null());
    bloom_filter_free(filter);
    filter = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 64 as u32,
    );
    assert!(!filter.is_null());
    bloom_filter_free(filter);
    filter = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 50000 as u32,
    );
    assert!(filter.is_null());
    alloc_test_set_limit(0 as i32);
    filter = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 1 as u32,
    );
    assert!(filter.is_null());
    alloc_test_set_limit(1 as i32);
    filter = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 1 as u32,
    );
    assert!(filter.is_null());
}
#[no_mangle]
pub extern "C" fn test_bloom_filter_insert_query() {
    let mut filter: *mut BloomFilter = 0 as *mut BloomFilter;
    filter = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 4 as u32,
    );
    assert!(
        bloom_filter_query(
            filter,
            b"test 1\0" as *const u8 as *const i8 as BloomFilterValue,
        ) == 0
    );
    assert!(
        bloom_filter_query(
            filter,
            b"test 2\0" as *const u8 as *const i8 as BloomFilterValue,
        ) == 0
    );
    bloom_filter_insert(
        filter,
        b"test 1\0" as *const u8 as *const i8 as BloomFilterValue,
    );
    bloom_filter_insert(
        filter,
        b"test 2\0" as *const u8 as *const i8 as BloomFilterValue,
    );
    assert!(
        bloom_filter_query(
            filter,
            b"test 1\0" as *const u8 as *const i8 as BloomFilterValue,
        ) != 0
    );
    assert!(
        bloom_filter_query(
            filter,
            b"test 2\0" as *const u8 as *const i8 as BloomFilterValue,
        ) != 0
    );
    bloom_filter_free(filter);
}
#[no_mangle]
pub extern "C" fn test_bloom_filter_read_load() {
    let mut filter1: *mut BloomFilter = 0 as *mut BloomFilter;
    let mut filter2: *mut BloomFilter = 0 as *mut BloomFilter;
    let mut state: [u8; 16] = [0; 16];
    filter1 = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 4 as u32,
    );
    bloom_filter_insert(
        filter1,
        b"test 1\0" as *const u8 as *const i8 as BloomFilterValue,
    );
    bloom_filter_insert(
        filter1,
        b"test 2\0" as *const u8 as *const i8 as BloomFilterValue,
    );
    bloom_filter_read(filter1, state.as_mut_ptr());
    bloom_filter_free(filter1);
    filter2 = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 4 as u32,
    );
    bloom_filter_load(filter2, state.as_mut_ptr());
    assert!(
        bloom_filter_query(
            filter2,
            b"test 1\0" as *const u8 as *const i8 as BloomFilterValue,
        ) != 0
    );
    assert!(
        bloom_filter_query(
            filter2,
            b"test 2\0" as *const u8 as *const i8 as BloomFilterValue,
        ) != 0
    );
    bloom_filter_free(filter2);
}
#[no_mangle]
pub extern "C" fn test_bloom_filter_intersection() {
    let mut filter1: *mut BloomFilter = 0 as *mut BloomFilter;
    let mut filter2: *mut BloomFilter = 0 as *mut BloomFilter;
    let mut result: *mut BloomFilter = 0 as *mut BloomFilter;
    filter1 = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 4 as u32,
    );
    bloom_filter_insert(
        filter1,
        b"test 1\0" as *const u8 as *const i8 as BloomFilterValue,
    );
    bloom_filter_insert(
        filter1,
        b"test 2\0" as *const u8 as *const i8 as BloomFilterValue,
    );
    filter2 = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 4 as u32,
    );
    bloom_filter_insert(
        filter2,
        b"test 1\0" as *const u8 as *const i8 as BloomFilterValue,
    );
    assert!(
        bloom_filter_query(
            filter2,
            b"test 2\0" as *const u8 as *const i8 as BloomFilterValue,
        ) == 0
    );
    result = bloom_filter_intersection(filter1, filter2);
    assert!(
        bloom_filter_query(
            result,
            b"test 1\0" as *const u8 as *const i8 as BloomFilterValue,
        ) != 0
    );
    assert!(
        bloom_filter_query(
            result,
            b"test 2\0" as *const u8 as *const i8 as BloomFilterValue,
        ) == 0
    );
    bloom_filter_free(result);
    alloc_test_set_limit(0 as i32);
    result = bloom_filter_intersection(filter1, filter2);
    assert!(result.is_null());
    bloom_filter_free(filter1);
    bloom_filter_free(filter2);
}
#[no_mangle]
pub extern "C" fn test_bloom_filter_union() {
    let mut filter1: *mut BloomFilter = 0 as *mut BloomFilter;
    let mut filter2: *mut BloomFilter = 0 as *mut BloomFilter;
    let mut result: *mut BloomFilter = 0 as *mut BloomFilter;
    filter1 = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 4 as u32,
    );
    bloom_filter_insert(
        filter1,
        b"test 1\0" as *const u8 as *const i8 as BloomFilterValue,
    );
    filter2 = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 4 as u32,
    );
    bloom_filter_insert(
        filter2,
        b"test 2\0" as *const u8 as *const i8 as BloomFilterValue,
    );
    result = bloom_filter_union(filter1, filter2);
    assert!(
        bloom_filter_query(
            result,
            b"test 1\0" as *const u8 as *const i8 as BloomFilterValue,
        ) != 0
    );
    assert!(
        bloom_filter_query(
            result,
            b"test 2\0" as *const u8 as *const i8 as BloomFilterValue,
        ) != 0
    );
    bloom_filter_free(result);
    alloc_test_set_limit(0 as i32);
    result = bloom_filter_union(filter1, filter2);
    assert!(result.is_null());
    bloom_filter_free(filter1);
    bloom_filter_free(filter2);
}
#[no_mangle]
pub extern "C" fn test_bloom_filter_mismatch() {
    let mut filter1: *mut BloomFilter = 0 as *mut BloomFilter;
    let mut filter2: *mut BloomFilter = 0 as *mut BloomFilter;
    filter1 = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 4 as u32,
    );
    filter2 = bloom_filter_new( 64 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 4 as u32,
    );
    assert!((bloom_filter_intersection(filter1, filter2)).is_null());
    assert!((bloom_filter_union(filter1, filter2)).is_null());
    bloom_filter_free(filter2);
    filter2 = bloom_filter_new( 128 as u32,
        Some(string_nocase_hash as unsafe extern "C" fn(*mut ()) -> u32), 4 as u32,
    );
    assert!((bloom_filter_intersection(filter1, filter2)).is_null());
    assert!((bloom_filter_union(filter1, filter2)).is_null());
    bloom_filter_free(filter2);
    filter2 = bloom_filter_new( 128 as u32,
        Some(string_hash as unsafe extern "C" fn(*mut ()) -> u32), 32 as u32,
    );
    assert!((bloom_filter_intersection(filter1, filter2)).is_null());
    assert!((bloom_filter_union(filter1, filter2)).is_null());
    bloom_filter_free(filter2);
    bloom_filter_free(filter1);
}
static mut tests_test_bloom_filter: [UnitTestFunction; 7] = {
    [
        Some(test_bloom_filter_new_free as unsafe extern "C" fn() -> ()),
        Some(test_bloom_filter_insert_query as unsafe extern "C" fn() -> ()),
        Some(test_bloom_filter_read_load as unsafe extern "C" fn() -> ()),
        Some(test_bloom_filter_intersection as unsafe extern "C" fn() -> ()),
        Some(test_bloom_filter_union as unsafe extern "C" fn() -> ()),
        Some(test_bloom_filter_mismatch as unsafe extern "C" fn() -> ()),
        None,
    ]
};
fn main_0_test_bloom_filter(mut _argc: i32, mut _argv: *mut *mut i8) -> i32 {
    run_tests(unsafe { tests_test_bloom_filter.as_mut_ptr() });
    return 0;
}
pub fn main_test_bloom_filter() {
    let mut args: Vec<*mut i8> = Vec::new();
    for arg in ::std::env::args() {
        args.push(
            (::std::ffi::CString::new(arg))
                .expect("Failed to convert argument into CString.")
                .into_raw(),
        );
    }
    args.push(::core::ptr::null_mut());
    {
        ::std::process::exit(main_0_test_bloom_filter(
            (args.len() - 1) as i32,
            args.as_mut_ptr() as *mut *mut i8,
        ) as i32)
    }
}
